#include <my_header.h>

/* Usage:  */
//上传
int transFile(int sockfd, char *filename) {
    train_t train;
    int fd = open(filename, O_RDWR);
    ERROR_CHECK(fd, -1, "open transFile");
    
    struct stat statbuf;
    fstat(fd, &statbuf);
    printf("filesize = %ld\n", statbuf.st_size);
    off_t filesize = statbuf.st_size;
    
    // 1. 发送文件总大小
    train.length = sizeof(filesize);
    memcpy(train.data, &filesize, sizeof(off_t));
    send(sockfd, &train, sizeof(train.length) + train.length, MSG_NOSIGNAL);
    
    // 2. 接收客户端已接收的大小
    off_t received_size = 0;
    recvn(sockfd, &train.length, sizeof(train.length));
    if (train.length == sizeof(off_t)) {
        recvn(sockfd, train.data, train.length);
        memcpy(&received_size, train.data, train.length);
        printf("Client has received %ld bytes, resuming from this point\n", received_size);
    }
    
    // 建立映射区
    char *p = (char *)mmap(NULL, filesize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    ERROR_CHECK(p, MAP_FAILED, "mmap");
    
    off_t offset = received_size;
    while (1) {
        if (offset >= filesize) {
            break;
        }
        
        if (filesize - offset > 1000) {
            train.length = 1000;
        } else {
            train.length = filesize - offset;
        }
        
        send(sockfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
        send(sockfd, p + offset, train.length, MSG_NOSIGNAL);
        offset += train.length;
    }
    
    // 发送结束标志
    train.length = 0;
    send(sockfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
    
    munmap(p, filesize);
    close(fd);
    return 0;
}
